package com.itic.appbase.framework.utils.wxpay;

import java.io.BufferedReader;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.StringReader;
import java.net.URL;
import java.net.URLConnection;
import java.security.KeyStore;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedMap;
import java.util.TreeMap;

import javax.net.ssl.SSLContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.conn.ssl.SSLContexts;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.jdom.Element;
import org.jdom.JDOMException;
import org.jdom.input.SAXBuilder;
import org.springframework.http.HttpEntity;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import net.sf.json.JSONObject;

import com.itic.appbase.framework.common.constants.ResponseCode;
import com.itic.appbase.framework.utils.wxpay.vo.CompanyPayVo;
import com.itic.appbase.framework.utils.DateHelper;
import com.itic.appbase.framework.utils.IdGen;
import com.itic.appbase.framework.utils.IpAddressHelper;
import com.itic.appbase.framework.utils.MD5Helper;
import com.itic.appbase.framework.utils.NumberStringHelper;
import com.itic.appbase.framework.utils.wxpay.vo.PayVo;
import com.itic.appbase.framework.utils.RefundVO;
import com.itic.appbase.framework.utils.StringHelper;
import com.itic.appbase.framework.utils.XmltoJsonUtil;
import com.itic.appbase.framework.utils.wxpay.HttpClientCustomSSL;
import com.itic.appbase.framework.utils.wxpay.SignUtils;
import com.itic.appbase.framework.utils.wxpay.StringUtils;
import com.itic.appbase.framework.utils.wxpay.XMLUtils;
import com.itic.appbase.framework.utils.wxrefound.WeixinRefoundConfig;
import com.itic.appbase.framework.utils.wxpay.vo.PaySuccessVo;
import com.itic.appbase.framework.utils.wxpay.vo.WxCompanyPay;
import com.itic.appbase.framework.utils.wxpay.vo.Wxpay;

  
public class WeixinPayUtil {
	
	 
	
	public static PaySuccessVo success( HttpServletRequest request, HttpServletResponse response ) throws Exception { 
		PaySuccessVo paySuccessVo = new PaySuccessVo();
		String orderNum = "999999999";
		String payTime = null;
		String payNo = null;
		request.setCharacterEncoding("UTF-8");  
	    response.setCharacterEncoding("UTF-8");  
	    response.setContentType("text/html;charset=UTF-8");  
	    response.setHeader("Access-Control-Allow-Origin", "*");   
	    InputStream in=request.getInputStream();  
	    ByteArrayOutputStream out=new ByteArrayOutputStream();  
	    byte[] buffer =new byte[1024];  
	    int len=0;  
	    while((len=in.read(buffer))!=-1){  
	        out.write(buffer, 0, len);  
	    }  
	    out.close();  
	    in.close();  
	    String msgxml=new String(out.toByteArray(),"utf-8");//xml数据  
	    System.out.println(msgxml); 
	    String xml2json = XmltoJsonUtil.xml2JSON(msgxml);
	    
	    JSONObject fromObject = JSONObject.fromObject(xml2json);
		JSONObject jsonObject = fromObject.getJSONObject("xml");
		
		 String result_code = jsonObject.getJSONArray("result_code").get(0).toString();
		 String return_code = jsonObject.getJSONArray("return_code").get(0).toString();
		 
		 if( result_code.equals("SUCCESS") && return_code.equals("SUCCESS") ){ 
			 
				/*这里没有测试成功，需要进一步研究的，回调验证
				 *  String appid  = jsonObject.getJSONArray("appid").get(0).toString();  
				 String back_type  = jsonObject.getJSONArray("bank_type").get(0).toString();  
				 String cash_fee  = jsonObject.getJSONArray("cash_fee").get(0).toString();  
				 String fee_type  = jsonObject.getJSONArray("fee_type").get(0).toString();  
				 String is_subscribe  = jsonObject.getJSONArray("is_subscribe").get(0).toString();  
				 String mch_id  = jsonObject.getJSONArray("mch_id").get(0).toString();  
				 String nonce_str  = jsonObject.getJSONArray("nonce_str").get(0).toString();  
				 String openid  = jsonObject.getJSONArray("openid").get(0).toString();  
				 
				 //String out_trade_no  = jsonObject.get("out_trade_no").toString();  
				 String sign  = jsonObject.getJSONArray("sign").get(0).toString();  
				 String time_end  = jsonObject.getJSONArray("time_end").get(0).toString();  
				 String total_fee  = jsonObject.getJSONArray("total_fee").get(0).toString();  
				 String trade_type  = jsonObject.getJSONArray("trade_type").get(0).toString();  
				 String transaction_id  = jsonObject.getJSONArray("transaction_id").get(0).toString(); 
				 
				 //生成签名
				 SortedMap<Object,Object> parameters = new TreeMap<Object,Object>(); 
				 parameters.put("appid", appid);
				 parameters.put("back_type", back_type);
				 parameters.put("cash_fee", cash_fee);
				 parameters.put("fee_type", fee_type);
				 parameters.put("is_subscribe", is_subscribe);
				 parameters.put("mch_id", mch_id);
				 parameters.put("nonce_str", nonce_str);
				 parameters.put("openid", openid);
				 parameters.put("out_trade_no", out_trade_no);
				 parameters.put("time_end", time_end);
				 parameters.put("total_fee", total_fee);
				 parameters.put("trade_type", trade_type);
				 parameters.put("transaction_id", transaction_id);
				 parameters.put("result_code", result_code);
				 parameters.put("return_code", return_code);
				
				 WeixinpayConfig weixinpayConfig = new WeixinpayConfig();
				 String sign2 = createSign("UTF-8",weixinpayConfig.getSecret(),parameters);
				 if( sign.equals(sign2) ){
					  
				 }*/
			 
			 
			     //处理自己的业务逻辑  
			     orderNum  = jsonObject.getJSONArray("out_trade_no").get(0).toString(); 
			     payTime = jsonObject.getJSONArray("time_end").get(0).toString();
			     payNo = jsonObject.getJSONArray("transaction_id").get(0).toString();
			     paySuccessVo.setOrderNo(orderNum);
			     paySuccessVo.setPayNo(payNo);
			     paySuccessVo.setPayTime(payTime);
			 
		 }
		 return paySuccessVo;
	}
	
	/**
	 * 微信支付工具类
	 * @param request
	 * @param weixinpayConfig
	 * @param vo
	 * @return
	 */
	public static  Map<String, Object> pay(HttpServletRequest request,Wxpay weixinpayConfig, PayVo vo) { 
		
		DataInputStream input = null;   
		  
		java.io.ByteArrayOutputStream out = null;   
		
		try{
			  //订单支付备注
		    // String body = "用户购买"+order.getTotalProduct()+"件商品，共消费"+order.getTotalMoney()+"元！";
		    //Wxpay weixinpayConfig = getWxpayConfig();
			
			String notifyUrl = vo.getNotifyUrl()==null?weixinpayConfig.getNotifyUrl():vo.getNotifyUrl();
		    String remortIP = IpAddressHelper.getRemortIP4();
		    String nonceStr = IdGen.uuid();
		    String money="1";
		    //如果是测试环境，则使用0.01元
			//String valueByKey = sysSettingService.getByKey("WXPAY_IS_OPEN_TEST");
			if( StringHelper.isNotBlank(weixinpayConfig.getIsTest()) && "open".equals(weixinpayConfig.getIsTest()) ){
				money = "1";
			}else{
				money = NumberStringHelper.mulString(vo.getTotalMoney(), "100",0);
				//money = totalMoney;
			}
		    
		    SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();  
	        parameters.put("appid", weixinpayConfig.getAppid());  
	        parameters.put("mch_id", weixinpayConfig.getMchId());  
	        //parameters.put("device_info", "1000");  
	        parameters.put("body", vo.getDesc());  
	        parameters.put("nonce_str", nonceStr);  
	        parameters.put("notify_url", notifyUrl);
	        parameters.put("out_trade_no", vo.getOrderNum());
	        parameters.put("spbill_create_ip", remortIP);
	        parameters.put("total_fee", money);
	        parameters.put("trade_type", "APP");
	        
		    
		    String sign = createSign("UTF-8",weixinpayConfig.getSecret(),parameters);
		    
		    StringBuilder sb = new StringBuilder();  
		    
	        sb.append("<xml>");  
	        sb.append("<appid>"+weixinpayConfig.getAppid()+"</appid>");  
	        sb.append("<mch_id>"+weixinpayConfig.getMchId()+"</mch_id>");  
	        //sb.append("<device_info>1000</device_info>");  
	        sb.append("<body>"+vo.getDesc()+"</body>");  
	        sb.append("<nonce_str>"+nonceStr+"</nonce_str>");  
	        sb.append("<notify_url>"+notifyUrl+"</notify_url>");  
	        sb.append("<out_trade_no>"+vo.getOrderNum()+"</out_trade_no>");  
	        sb.append("<spbill_create_ip>"+remortIP+"</spbill_create_ip>");  
	        sb.append("<total_fee>"+money+"</total_fee>");  
	        sb.append("<trade_type>APP</trade_type>");  
	        sb.append("<sign>"+sign+"</sign>");  
	        sb.append("</xml>"); 
	        
	        String paramXml = sb.toString();
	        		
	        byte[] xmlData = paramXml.getBytes(); 
			
			
			URL url = new URL(weixinpayConfig.getWxurl());
			URLConnection urlCon = url.openConnection();   
			  
	        urlCon.setDoOutput(true);   
	  
	        urlCon.setDoInput(true);   
	  
	        urlCon.setUseCaches(false);   
	        
	        //将xml数据发送到位置服务   
	        
	        urlCon.setRequestProperty("Content-Type", "text/xml");   
	  
	        urlCon.setRequestProperty("Content-length",String.valueOf(xmlData.length));   
	  
	        DataOutputStream printout = new DataOutputStream(urlCon.getOutputStream());   
	  
	        printout.write(xmlData);   
	  
	        printout.flush();   
	  
	        printout.close();   
	  
	        input = new DataInputStream(urlCon.getInputStream());   
	  
	       @SuppressWarnings("unused")
		   byte[] rResult;   
	  
	        out = new java.io.ByteArrayOutputStream();   
	  
	       byte[] bufferByte = new byte[256];   
	  
	       int l = -1;   
	  
	       @SuppressWarnings("unused")
		   int downloadSize = 0;   
	  
	       while ((l = input.read(bufferByte)) > -1) {   
	  
	            downloadSize += l;   
	  
	            out.write(bufferByte, 0, l);   
	  
	            out.flush();   
	  
	        }   
		}catch(Exception e){
			e.printStackTrace();
		}finally{
			if( null != input ){
				try {
					input.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			
			if( null != out ){
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
  
        String string = out.toString();
        Map<String, Object> jsonPay = getJsonPay(weixinpayConfig,string);
        return jsonPay;
    }  
	
	public static Map<String, Object> companypay(HttpServletRequest request, WxCompanyPay weixinCompanyConfig, CompanyPayVo vo) {

		DataInputStream input = null;

		java.io.ByteArrayOutputStream out = null;
		String response = null;
		try {
			// 订单支付备注
			// String body =
			// "用户购买"+order.getTotalProduct()+"件商品，共消费"+order.getTotalMoney()+"元！";
			/*<xml>
			<amount>500</amount>
			<bank_code>1021</bank_code>
			<account_type>1</account_type>
			<bank_note>中国工商银行工资发放</bank_note>
			<desc>test</desc>
			<enc_bank_no>so40iz98I8P5DRdMpOqYK/SOWdDhW8fQhlCQEuxV//LLvRZs51B4z8yeIe3X7aYyRdJGdYy18RLpJAZEYrZ9y981pB55aU9ZqT1So7Ypc1URahkLAOggUk/nKur750Lei6D0QQ1Q/B1aiYHA+IPwZH1YEjsIra9tvY7LjYgBjUsEnWx51piaL/Bv4gLvK5lo+lT7iTT2eiLD95y7PcV9U5p5zAxRMPiy6dtJt1UYfwNnbHMZbP+hdTmUhBup2JpJbk+9xchWzrwrFUQPYpB4caTOx98xubwrKrOO/xM2lt9GbRsv1GA5vF04jIiWx/dtkjQvWuPlBOTmkSDl6J0ErQ==</enc_bank_no>
			<enc_true_name>WrmNNBewyx8KJGMtrsYUf3RAmMsaHByOIu/wSjFKy/ouMeg1msRxbwzksPDRjI7OA6pvb3Ty7RQKQTGAjFdaxa10c9Dn0BqLPapP1svj000TWRd1VRJriUqy0macXZu6Pxx9bZd9ngiUcXbrVpGA10BMMwOFJ5VEt7aFJjUJSw2CCZNgj1HOVskm3abNl1eMWyzDCHVjH6uXnT8of17g5GTELTNn2ccNMTmfkUrVJopHeXTA5Yd+uKx5Tgst4IonNiHb+dFWsiGG8aOY29nqHWHw3e+vVRk/0DwEAJzaJlWjb110/TtjYjkquZwFh9XL8GncrNfoBjUz2rtvmhb5Rg==</enc_true_name>
			<mch_id>2302758702</mch_id>
			<nonce_str>50780e0cca98c8c8e814883e5caa672e</nonce_str>
			<partner_trade_no>1212121221278</partner_trade_no>
			<sign>1b3375482ac61d952aab56b534608971</sign>

			</xml>*/
			// Wxpay weixinpayConfig = getWxpayConfig();

			String remortIP = IpAddressHelper.getRemortIP4();
			String nonceStr = "ibuaiVcKdpRxkhJA";
			SortedMap<Object, Object> parameters = new TreeMap<Object, Object>();
			parameters.put("mchid", "1488125002");
			parameters.put("amount", "1");
			parameters.put("desc", "测试");
			parameters.put("device_info", "1000");
			
			parameters.put("mch_appid", weixinCompanyConfig.getAppid());
			parameters.put("nonce_str", nonceStr);
			parameters.put("openid", vo.getOpenid());
			parameters.put("partner_trade_no", vo.getPartner_trade_no());
			parameters.put("re_user_name", "APP");
			parameters.put("spbill_create_ip", remortIP);

			String sign = createSign("UTF-8", weixinCompanyConfig.getSecret(), parameters);

			StringBuilder sb = new StringBuilder();

			sb.append("<xml>");
			sb.append("<amount>" + vo.getAmount() + "</amount>");
			sb.append("<check_name>" + "NO_CHECK" + "</check_name>");
			sb.append("<desc>APP</desc>");
			sb.append("<mchid>" + weixinCompanyConfig.getMchId() + "</mchid>");
			sb.append("<mch_appid>" + weixinCompanyConfig.getAppid() + "</mch_appid>");
			sb.append("<nonce_str>" + nonceStr + "</nonce_str>");
			sb.append("<openid>" + vo.getOpenid() + "</openid>");
			sb.append("<partner_trade_no>" + vo.getPartner_trade_no() + "</partner_trade_no>");
			sb.append("<re_user_name>" + "测试" + "</re_user_name>");
			sb.append("<sign>"+sign+"</sign>");
			sb.append("<spbill_create_ip>" + remortIP + "</spbill_create_ip>");
			sb.append("</xml>");

			String paramXml = sb.toString();
			//使用CA证书
			response = ssl(weixinCompanyConfig.getWxurl(),paramXml,weixinCompanyConfig);  
			
			byte[] xmlData = paramXml.getBytes();

			URL url = new URL(weixinCompanyConfig.getWxurl());
			
	        //Map<String, String> responseMap = xmlUtil.parseXml(response);
			URLConnection urlCon = url.openConnection();

			urlCon.setDoOutput(true);

			urlCon.setDoInput(true);

			urlCon.setUseCaches(false);

			// 将xml数据发送到位置服务

			urlCon.setRequestProperty("Content-Type", "text/xml");

			urlCon.setRequestProperty("Content-length", String.valueOf(xmlData.length));

			DataOutputStream printout = new DataOutputStream(urlCon.getOutputStream());

			//printout.write(xmlData);
			//response

			printout.flush();

			printout.close();

			input = new DataInputStream(urlCon.getInputStream());

			@SuppressWarnings("unused")
			byte[] rResult;

			out = new java.io.ByteArrayOutputStream();

			byte[] bufferByte = new byte[256];

			int l = -1;

			@SuppressWarnings("unused")
			int downloadSize = 0;

			while ((l = input.read(bufferByte)) > -1) {

				downloadSize += l;

				out.write(bufferByte, 0, l);

				out.flush();

			}
			
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (null != input) {
				try {
					input.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}

			if (null != out) {
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		
		
		String string = out.toString();
		
		System.out.println(string);
		Map<String, Object> jsonPay = getJsonCompanyPay(weixinCompanyConfig, response);
		return jsonPay;
	}
	
	private static String ssl(String url,String data,WxCompanyPay WxCompanyPay){  
        StringBuffer message = new StringBuffer();  
        try {  
            KeyStore keyStore  = KeyStore.getInstance("PKCS12");  
            FileInputStream instream = new FileInputStream(new File("C://Users//Administrator//Desktop//cert//cert//apiclient_cert.p12"));  
            keyStore.load(instream, WxCompanyPay.getMchId().toCharArray());  
            // Trust own CA and all self-signed certs  
            SSLContext sslcontext = SSLContexts.custom()  
                    .loadKeyMaterial(keyStore, WxCompanyPay.getMchId().toCharArray())  
                    .build();  
            // Allow TLSv1 protocol only  
            SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(  
                    sslcontext,  
                    new String[] { "TLSv1" },  
                    null,  
                    SSLConnectionSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER);  
            CloseableHttpClient httpclient = HttpClients.custom()  
                    .setSSLSocketFactory(sslsf)  
                    .build();  
            HttpPost httpost = new HttpPost(url);  
  
            httpost.addHeader("Connection", "keep-alive");  
            httpost.addHeader("Accept", "*/*");  
            httpost.addHeader("Content-Type", "application/x-www-form-urlencoded; charset=UTF-8");  
            httpost.addHeader("Host", "api.mch.weixin.qq.com");  
            httpost.addHeader("X-Requested-With", "XMLHttpRequest");  
            httpost.addHeader("Cache-Control", "max-age=0");  
            httpost.addHeader("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 6.0) ");  
            httpost.setEntity(new StringEntity(data, "UTF-8"));  
            //System.out.println("executing request" + httpost.getRequestLine());  
  
            CloseableHttpResponse response = httpclient.execute(httpost);  
            try {  
                //HttpEntity entity = (HttpEntity) response.getEntity();  
                org.apache.http.HttpEntity entity = response.getEntity();
  
                //System.out.println("----------------------------------------");  
                //System.out.println(response.getStatusLine());  
                if (entity != null) {  
                    //System.out.println("Response content length: " + entity.getContentLength());  
                    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(((org.apache.http.HttpEntity) entity).getContent(),"UTF-8"));  
                    String text;  
                    while ((text = bufferedReader.readLine()) != null) {  
                        message.append(text);  
                    }  
                }  
                EntityUtils.consume((org.apache.http.HttpEntity) entity);  
            } catch (IOException e) {  
                e.printStackTrace();  
            } finally {  
                response.close();  
            }  
        } catch (Exception e1) {  
            e1.printStackTrace();  
        }   
  
        return message.toString();  
    }  
      
	public static void back(HttpServletRequest request,Wxpay weixinpayConfig, PayVo vo) { 
		
	}
	
	
	public static Map<String,Object> getJsonPay(Wxpay weixinpayConfig,String xml){
		HashMap<String, Object> result = new HashMap<String,Object>();
		if( StringHelper.isNotBlank(xml) ){
			String date = DateHelper.getDate("MMddhhmmss");
			//WeixinpayConfig weixinpayConfig = new WeixinpayConfig();
			//Wxpay weixinpayConfig = getWxpayConfig();
			String xml2json = XmltoJsonUtil.xml2JSON(xml);
			JSONObject fromObject = JSONObject.fromObject(xml2json);
			JSONObject jsonObject = fromObject.getJSONObject("xml");
			
			
			
			Object nonce_str = jsonObject.getJSONArray("nonce_str").get(0);
			result.put("nonce_str", nonce_str.toString());
			
			//Object device_info = jsonObject.getJSONArray("device_info").get(0);
			//result.put("device_info", device_info.toString());
			
			Object appid = jsonObject.getJSONArray("appid").get(0);
			result.put("appid", appid.toString());
			
			Object sign = jsonObject.getJSONArray("sign").get(0);
			result.put("sign", sign.toString());
			
			Object trade_type = jsonObject.getJSONArray("trade_type").get(0);
			result.put("trade_type", trade_type.toString());
			
			Object mch_id = jsonObject.getJSONArray("mch_id").get(0);
			result.put("mch_id", mch_id.toString());
			
			Object prepay_id = jsonObject.getJSONArray("prepay_id").get(0);
			result.put("prepay_id", prepay_id.toString());
			
			result.put("timestamp", date);
			
			SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();  
			parameters.put("appid",appid.toString());
			parameters.put("partnerid", mch_id.toString());
			parameters.put("prepayid", prepay_id.toString());
			parameters.put("package", "Sign=WXPay");
			parameters.put("noncestr", nonce_str.toString());
			parameters.put("timestamp", date);
			
			String sign2 = createSign("MD5",weixinpayConfig.getSecret(),parameters);
			result.put("sign", sign2);
		}
		
		return result;
	}
	
	public static Map<String,Object> getJsonCompanyPay(WxCompanyPay weixinpayConfig,String xml){
		HashMap<String, Object> result = new HashMap<String,Object>();
		if( StringHelper.isNotBlank(xml) ){
			String date = DateHelper.getDate("MMddhhmmss");
			//WeixinpayConfig weixinpayConfig = new WeixinpayConfig();
			//Wxpay weixinpayConfig = getWxpayConfig();
			String xml2json = XmltoJsonUtil.xml2JSON(xml);
			JSONObject fromObject = JSONObject.fromObject(xml2json);
			JSONObject jsonObject = fromObject.getJSONObject("xml");
			System.out.println(jsonObject);
			
			
			Object nonce_str = jsonObject.getJSONArray("nonce_str").get(0);
			result.put("nonce_str", nonce_str.toString());
			
			//Object device_info = jsonObject.getJSONArray("device_info").get(0);
			//result.put("device_info", device_info.toString());
			
			Object appid = jsonObject.getJSONArray("appid").get(0);
			result.put("appid", appid.toString());
			
			Object sign = jsonObject.getJSONArray("sign").get(0);
			result.put("sign", sign.toString());
			
			Object trade_type = jsonObject.getJSONArray("trade_type").get(0);
			result.put("trade_type", trade_type.toString());
			
			Object mch_id = jsonObject.getJSONArray("mch_id").get(0);
			result.put("mch_id", mch_id.toString());
			
			Object prepay_id = jsonObject.getJSONArray("prepay_id").get(0);
			result.put("prepay_id", prepay_id.toString());
			
			result.put("timestamp", date);
			
			SortedMap<Object,Object> parameters = new TreeMap<Object,Object>();  
			parameters.put("appid",appid.toString());
			parameters.put("partnerid", mch_id.toString());
			parameters.put("prepayid", prepay_id.toString());
			parameters.put("package", "Sign=WXPay");
			parameters.put("noncestr", nonce_str.toString());
			parameters.put("timestamp", date);
			
			String sign2 = createSign("MD5",weixinpayConfig.getSecret(),parameters);
			result.put("sign", sign2);
		}
		
		return result;
	}
	
	/** 
     * 微信支付签名算法sign 
     * @param characterEncoding 
     * @param parameters 
     * @return 
     */  
    @SuppressWarnings("rawtypes")
	public static String createSign(String characterEncoding,String key,SortedMap<Object,Object> parameters){  
        StringBuffer sb = new StringBuffer();  
        Set es = parameters.entrySet();//所有参与传参的参数按照accsii排序（升序）  
        Iterator it = es.iterator();  
        while(it.hasNext()) {  
            Map.Entry entry = (Map.Entry)it.next();  
            String k = (String)entry.getKey();  
            Object v = entry.getValue();  
            if(null != v && !"".equals(v)   
                    && !"sign".equals(k) && !"key".equals(k)) {  
                sb.append(k + "=" + v + "&");  
            }  
        }  
        sb.append("key=" + key);  
        String sign = MD5Helper.MD5Encode(sb.toString(), characterEncoding).toUpperCase();  
        return sign;  
    }  
	
	
	public Map<String,String> getParamMap(HttpServletRequest request){
		Map<String,String> params = new HashMap<String,String>();
		Map<String,String[]> requestParams = request.getParameterMap();
		if( null != requestParams ){
			for( Iterator<String> iter = requestParams.keySet().iterator();iter.hasNext();){
				String name = (String)iter.next();
				String[] values = (String[]) requestParams.get(name);
				String valueStr = "";
				for( int i=0;i<values.length;i++){
					valueStr=(i==values.length-1)?valueStr+values[i]:valueStr+values[i]+",";
				}
				//乱码解决，这段代码再出现乱码时使用。如果masign和sign不相等也可以使用这段代码
				//valueStr=new String(valueStr.getBytes("ISO-8859-1"),"gbk");
				params.put(name,valueStr);
				
			}
		}
		return params;
	}
	
	
	public static String setXml(String return_code,String return_msg){  
        return "<xml><return_code><![CDATA["+return_code+"]]></return_code><return_msg><![CDATA["+return_msg+"]]></return_msg></xml>";  
    } 
	
	/**
	 * 微信退款方法
	 * @param orderNum
	 * @param refundFee
	 * @param totalRefundFee
	 * @return
	 * @throws Exception
	 */
	public static String wxRefund(String orderNum,String refundFee,String totalRefundFee) throws Exception {
		 WeixinRefoundConfig config = new WeixinRefoundConfig();
		 String nonce_str1 =  StringUtils.getStrRandom(28);
		 //获取签名  enc_bank_no
	     SortedMap<Object,Object> parameters1 = new TreeMap<Object,Object>();
	     parameters1.put("appid", config.getAPP_ID());
		 parameters1.put("mch_id", config.getMCH_ID());
		 parameters1.put("nonce_str", nonce_str1);
		 parameters1.put("out_trade_no", orderNum);
		 String uuid = IdGen.uuid();
		 parameters1.put("out_refund_no", uuid);
		 parameters1.put("refund_fee", refundFee);
		 parameters1.put("total_fee", totalRefundFee);
		 String sign1 = SignUtils.creatSign(config.getCHARSET(), config.getKEY(),parameters1);
		 //请求企业付款
		 TreeMap<String, String> tmap1 = new TreeMap<String, String>();
		 tmap1.put("appid", config.getAPP_ID());
		 tmap1.put("mch_id", config.getMCH_ID());
		 tmap1.put("nonce_str", nonce_str1);
		 tmap1.put("out_trade_no", orderNum);
		 tmap1.put("out_refund_no", uuid);
		 tmap1.put("refund_fee", refundFee);
		 tmap1.put("total_fee",totalRefundFee);
		 tmap1.put("sign", sign1);
		 tmap1.put("notify_url", config.getNotify_url());
		 String xml2 = XMLUtils.getFilterRequestXml(tmap1);
		 String  xml3= HttpClientCustomSSL.httpClientResultRefound(xml2,config.getCHARSET(),config.getMCH_ID(),config.getCA_LICENSE());
		 return xml3;
	}
	/**
	 * 解析微信支付返回的xml
	 * @param xml
	 * @return
	 * @throws JDOMException
	 * @throws IOException
	 */
	public static  RefundVO  parseXMLToRefundVO(String xml) throws JDOMException, IOException {
		String data = XMLUtils.Progress_resultParseXml(xml);
		StringReader read = new StringReader(xml);
		InputSource source = new InputSource(read);
		SAXBuilder sb = new SAXBuilder();
		org.jdom.Document doc;
		doc = (org.jdom.Document) sb.build(source);
		org.jdom.Element root = doc.getRootElement();
		List<org.jdom.Element> list = root.getChildren();
		RefundVO refundVO = null;
		String return_msg = "";
		String return_code = "";
		String result_code = "";
		String err_code_des = "";
		if(!list.isEmpty()) {
			for(Element element : list) {
				String name = element.getName();
				switch (name) {
					case "return_msg":
						return_msg = element.getText();
						break;
					case "return_code":
						return_code = element.getText();
						break;
					case "result_code":
						result_code = element.getText();
						break;
					case "err_code_des":
						err_code_des = element.getText();
						break;
				}
			}
		}
		if(org.apache.commons.lang3.StringUtils.isNotEmpty(return_code)) {
			if("SUCCESS".equals(return_code)) {
				if("SUCCESS".equals(result_code)) {
					refundVO = new RefundVO("10000", err_code_des);
				}else 
					refundVO = new RefundVO("20000", err_code_des);
			}else
				refundVO = new RefundVO("2000", return_msg);
		}
		return refundVO;
	}
	
	 /**
     * IO解析获取微信的数据
     * 
     * @param request
     * @return
     */
	public static String getXmlString(HttpServletRequest request) throws IOException {
        BufferedReader reader = null;
        String line = "";
        String xmlString = null;
        reader = request.getReader();
        StringBuffer inputString = new StringBuffer();

        while ((line = reader.readLine()) != null) {
            inputString.append(line);
        }
        xmlString = inputString.toString();
        return xmlString;
    }
}
